home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xnetbris.00 / xnetbris / client-text.c < prev    next >
C/C++ Source or Header  |  1995-07-23  |  8KB  |  308 lines

  1. /*
  2.    This is the text only client for Netbrisk (used mainly for debugging)
  3.     Copyright (C) 1995 Brendan Bartlett
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. /* The "protocol" for the server is as follows -
  21.  *  - a packet of type INFORM_TYPE telling the client the numplayers and play_type
  22.  * - a MOVE_TYPE packet, with the brisk card in the card.
  23.  *
  24.  * - 3 MOVE_TYPE packets, giving the client the cards in their hand
  25.  *
  26.  * after the beginning point, the game is fairly normal with
  27.  * - packets of MOVE_TYPE or MESSAGE_TYPE 
  28.  * - a very important packets of MOVE_EXPECTED tells the client that
  29.  *      a move is expected from them now, and the server is idling.
  30.  *
  31.  *
  32.  * the client can do whatever they want with these packets
  33.  * "Fabio" and Brendan Bartlett, 1995
  34. */
  35.  
  36. /* Arggg!
  37.  * For the servers convience, the graphics are a little screwed up
  38.  * the card->weight:
  39.  *      9           ace
  40.  *      8           three
  41.  *      7           king (re)
  42.  *      6           girl (donna)
  43.  *     .
  44.  *     .
  45.  *     .
  46. */
  47.  
  48.  
  49.  
  50. #include <stdio.h>
  51. #include <signal.h>
  52. #include <stdlib.h>
  53. #include <sys/types.h>
  54. #include <sys/time.h>
  55. #include <sys/socket.h>
  56. #include <netinet/in.h>
  57. #include <arpa/inet.h>
  58. #include <netdb.h>
  59. #include <unistd.h>
  60. #include <sys/types.h>
  61. #include <sys/uio.h>
  62.  
  63. #include "brisk.h"
  64.  
  65. static int server_fd;
  66. static int numplayers;
  67. static int play_type;
  68. static int my_number;                /* which player number this client is */
  69.  
  70. static struct card brisk;
  71. static struct card hand[3];                             /* This is an array with the current cards in this players hand */
  72.  
  73. static int get_card(int);                                 /* reads a new card from the server */
  74. static void play_brisk(void);
  75. static void update_cards(void);             /* some sort of change to the hand -- tell the user */
  76.  
  77. int handler(int signum);
  78. int start_client(char * hostname, int port);
  79. void main(int, char *[]);
  80.  
  81. int handler(int signum)
  82. {
  83.   fprintf(stderr, "got SIGPIPE, client cleaning..\n");
  84.   
  85.   close(server_fd);
  86.   exit(0);
  87. }
  88.  
  89. void main(int argc, char *argv[])
  90. {
  91.   int port = 10000;
  92.   struct packet p;
  93.   int i;
  94.  
  95.   signal(SIGPIPE, handler);
  96.  
  97.   if(argc == 1)
  98.     {
  99.       printf("usage: %s <hostname> <port>\n", argv[0]);
  100.       printf(" hostname is the name where the SERVER is running.\n");
  101.       printf(" port is an optional setting to connect to the server.\n");
  102.       exit(0);
  103.     }
  104.  
  105.   if(argc == 3)
  106.     port = atoi(argv[2]);
  107.  
  108.   if(!start_client(argv[1], port))
  109.     {
  110.       printf("cannot connect to server '%s'\n", argv[1]);
  111.       exit(0);
  112.     }
  113.  
  114.  
  115.   /* Read in our hand from the server */
  116.  
  117.  
  118.   for(i = 0; i < 3; i++)
  119.     {
  120.       get_card(i);
  121.       printf(" %d %d \t", hand[i].suit, hand[i].weight);
  122.     }
  123.  
  124.   /* Read in the brisk from the server */
  125.  
  126.   read(server_fd, &p, sizeof(struct packet));
  127.  
  128.   if(p.type != MOVE_TYPE || p.data.move.player != 5)
  129.     {
  130.       fprintf(stderr, "server did not send the brisk card!\n");
  131.       exit(0);
  132.     }
  133.   
  134.   memcpy(&brisk, &p.data.move.play_card, sizeof(struct card));
  135.   printf("\nbrisk: %d %d\n", brisk.suit, brisk.weight);
  136.   
  137.   printf("\n");
  138.   play_brisk();
  139.  
  140. }
  141. /*
  142.  * This routine will read from the server for a packet of MOVE_TYPE (or DEAL_TYPE) and will fill in the
  143.  * given card in the hand[] array.
  144.  *
  145.  * If the packet is of type DEAL_TYPE, the argument 'card' is ignored and the suggested value in the
  146.  * packet is used instead.
  147.  *
  148.  * Returns 0 on failure
  149.  *         1 on success 
  150.  */
  151. static int get_card(int card)
  152. {
  153.   struct packet p;
  154.   
  155.   read(server_fd, &p, sizeof(struct packet));
  156.  
  157.   if( (p.type != MOVE_TYPE) && (p.type != DEAL_TYPE) )
  158.     {
  159.       fprintf(stderr, "FATAL ERROR: MOVE_TYPE or DEAL_TYPE expected!\n");
  160.       return 0;
  161.     }
  162.  
  163.   if(p.type == DEAL_TYPE)
  164.     memcpy(&hand[p.data.deal.rec_place], &p.data.deal.deal_card, sizeof(struct card));
  165.   else
  166.     memcpy(&hand[card], &p.data.move.play_card, sizeof(struct card));
  167.  
  168.   return 1;
  169. }
  170.  
  171. /* *
  172.  * This updates the cards that the user sees on the scren.
  173.  *
  174.  */
  175. static void update_cards(void)
  176. {
  177.   int i;
  178.  
  179.   for(i = 0; i < 3; i++)
  180.     printf("%d %d \t", hand[i].suit, hand[i].weight);
  181.   
  182.   printf("\n");
  183. }
  184.  
  185. static void play_brisk(void)
  186. {
  187.   struct packet in, out;
  188.   char buf[80];
  189.   int i;
  190.  
  191.   while(1)
  192.     {
  193.       read(server_fd, &in, sizeof(struct packet));
  194.  
  195.       
  196.       switch(in.type)
  197.     {
  198.     case END_GAME:
  199.       printf("That's the end of the frigging game!\n");
  200.       close(server_fd);
  201.       exit(0);
  202.  
  203.     case MESSAGE_TYPE:
  204.       printf("message: [%s]\n", in.data.message.string);
  205.       break;
  206.     case MOVE_TYPE:
  207.       printf("player %d played card %d %d\n", in.data.move.player, in.data.move.play_card.suit, in.data.move.play_card.weight);
  208.       break;
  209.     case SCORE_UPDATE:
  210.       printf("\nplayer %d won last hand!\n", in.data.score.lastwin);
  211.       printf("scores: %d %d\n", in.data.score.scores[0], in.data.score.scores[1]);
  212.       break;
  213.  
  214.     case DEAL_TYPE:
  215.  
  216.       memcpy(&hand[in.data.deal.rec_place], &in.data.deal.deal_card, sizeof(struct card));
  217.  
  218. /*
  219.       update_cards();
  220. */
  221.       break;
  222.     case INFORM_TYPE:
  223.       printf("server send INFORM_TYPE. Not at start of game\n");
  224.       break;
  225.     case MOVE_EXPECTED:
  226.       if(in.data.move.player != my_number)
  227.         break;
  228.  
  229.       out.type = MOVE_TYPE;
  230.       out.data.move.player = my_number;
  231.  
  232.       do
  233.         {
  234.           update_cards();
  235.  
  236.           printf("hey, hosehead, enter a card\n");
  237.           fgets(buf, 80, stdin);
  238.           sscanf(buf, "%d %d", &out.data.move.play_card.suit, &out.data.move.play_card.weight);
  239.  
  240.           write(server_fd, &out, sizeof(struct packet));
  241.  
  242.           read(server_fd, &in, sizeof(struct packet));
  243.         
  244.           if(in.type == ILLEGAL_MOVE)
  245.         printf("illegal card %d %d\n", out.data.move.play_card.suit, out.data.move.play_card.weight);
  246.         }
  247.       while(in.type == ILLEGAL_MOVE);
  248.  
  249.       hand[in.data.ok.cardpos].suit = -1;
  250.       hand[in.data.ok.cardpos].weight = -1;
  251.     }
  252.     }
  253. }
  254.       
  255.  
  256. int start_client(char *hostname, int port)
  257. {
  258.   struct sockaddr_in addr;
  259.   struct protoent *proto;
  260.   struct hostent *host;
  261.   struct packet p;
  262.  
  263.   proto = getprotobyname("tcp");
  264.   if(!proto)
  265.     {
  266.       printf("tcp not supported here.\n");
  267.       return 0;
  268.     }
  269.  
  270.   host = gethostbyname(hostname);
  271.  
  272.   if(!host)
  273.     {
  274.       printf("cannot find host '%s'\n", host);
  275.       return 0;
  276.     }
  277.  
  278.   addr.sin_family = AF_INET;
  279.   addr.sin_port = htons(port);
  280.   addr.sin_addr.s_addr = inet_addr(hostname);
  281.   memcpy((char *)&addr.sin_addr, (char *)(*host->h_addr_list), host->h_length);
  282.   server_fd = socket(PF_INET, SOCK_STREAM, proto->p_proto);
  283.   if(server_fd == -1)
  284.     {
  285.       perror("socket");
  286.       return 0;
  287.     }
  288.  
  289.   printf("Attemping to connect to port %i of server %s.\n", port, hostname);
  290.   
  291.   if(connect(server_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
  292.     {
  293.       perror("connect");
  294.       return 0;
  295.     }
  296.  
  297.   read(server_fd, &p, sizeof(struct packet));
  298.   
  299.   printf("# players %d, play_type %d.  I player # %d\n", p.data.inform.numplayers, p.data.inform.play_type,
  300.      p.data.inform.yournumber);
  301.  
  302.   numplayers = p.data.inform.numplayers;
  303.   play_type = p.data.inform.play_type;
  304.   my_number = p.data.inform.yournumber;
  305.  
  306.   return 1;
  307. }
  308.